package com.pxr.reflectiondemo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class TestDemo {
    public static void main(String[] args) {
        test3();
    }

    /**
     * 反射工具类：Class工具类
     */
    public static void test1() {
        //获取 类 描述类 Class的三种途径：

        //(1)类名.class
       Class<Student> clazz= Student.class;

        //(2)Class的forName静态方法
        try {
            Class clazz1 = Class.forName("com.pxr.reflectiondemo.Student");// 包路径名
            System.out.println("clazz==clazz1"+(clazz==clazz1));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //(3)实例对象.getClass方法
        Student student = new Student();
        Class clazz2 = student.getClass(); // 继承自Object类的方法
        System.out.println("clazz==clazz2"+(clazz==clazz2));

        try {
            Student student1 = clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 反射工具类：Constructor工具类
     */
    public static void test2() {
        // 获取 类 描述类 Class的三种途径：
        // (1)类名.class
        Class<Student> clazz = Student.class;
        try {
            //获取类的构造方法对象
            Constructor<Student> constructor = clazz.getDeclaredConstructor(String.class,String.class,double.class);
            //调用构造方法对象的newInstance方法创建一个实例对象
            Student student = constructor.newInstance("张三","101010",88);
            System.out.println("通过构造方法对象获取实例变量");
            System.out.println(student);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 反射工具类：Field工具类
     */
    public static void test3() {
        //(3)实例对象.getClass方法
        Student student = new Student();
        Class clazz = student.getClass();

        try {
            // 获取一个指定名字的属性对象
            Field field = clazz.getDeclaredField("stuName");
            Field field1 = clazz.getDeclaredField("stuNum");
            // 设值属性对象可以操作私有属性
            field.setAccessible(true);
            field1.setAccessible(true);
            // 调用属性对象的set方法，给属性对象进行设值；需要绑定该属性来自的实例对象
            field.set(student,"张三");
            field1.set(student,"101010");
            System.out.println(student);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 反射工具类：Field工具类
     */
    public static void test4() {
        //(3)实例对象.getClass方法
        Student student = new Student();
        Class clazz = student.getClass();
        try {
            // 获取一个指定名字的方法对象
            Method method = clazz.getDeclaredMethod("doStuding",String.class);
            // 使用invoke调用method对象，让该方法对象动态执行起来
            method.invoke(student,"哈哈");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
